<!--
    @Title: LeaferRuler
    @Author  dudalei
    @Package 
    @Date  2024/10/14 15:50
    @description: 标尺线插件


-->
<script setup lang="ts">
import {
  EditorEvent,
  EditorMoveEvent,
  EditorRotateEvent,
  EditorScaleEvent,
  EditorSkewEvent,
} from 'leafer-editor'
import type { UI } from 'leafer-ui'
import { cloneDeep } from 'lodash-es'
import { NodeType } from '@/components/LeaferApp/public'
import { formSelectInjectKey } from '@/components/LeaferApp/LeaferInjectKeys'

// 导入画布对象
const leaferApp = inject(LeaferInjectKey)

// 属性表单
const initForm = {
  // 元素id
  id: '',
  //zIndex层级
  zIndex: 0,
  //x轴坐标
  x: 0,
  // y轴坐标
  y: 0,
  // 宽度
  width: 0,
  // 高度
  height: 0,
  // 旋转角度
  rotation: 0,
  // x轴缩放
  scaleX: 1,
  // y轴缩放
  scaleY: 1,
  //x轴倾斜
  skewX: 0,
  // y轴倾斜
  skewY: 0,
  // 填充颜色
  fill: '',
  // 描边属性
  // 描边颜色
  stroke: '',
  //描边的宽度, 默认为 1。
  strokeWidth: 1,
  // 描边的端点形状，默认为 none。
  strokeCap: 'none',
  // 描边的拐角处理，默认为 miter 。
  strokeJoin: 'miter',
  // 虚线描边的数值。
  dashPattern: [10, 20],
  // 虚线描边的起点偏移值。
  dashOffset: 0,
  // 是否可编辑
  editable: true,
  // 是否锁定
  locked: false,
  lockRatio: false,
  // 数据属性
  data: {},
}
// 元素属性表单
const form = ref<Record<string, any>>(cloneDeep(initForm))

// 是否展示填充颜色
const showFill = computed(() => {
  return typeof form.value.fill === 'string'
})

// 画布属性
const appForm = ref<Record<string, any>>({
  // 背景颜色
  fill: '',
  // 宽度
  width: 0,
  // 高度
  height: 0,
})

const userDataTemp = ref('')
const userData = computed({
  get() {
    return JSON.stringify(form.value.data)
  },
  set(value) {
    form.value.data = cloneDeep(value)
  },
})
const userDataChange = () => {
  try {
    userData.value = JSON.parse(userDataTemp.value)
  } catch (e) {
    console.error(e)
  }
}

/**
 * 不同类型的属性
 */
const attrs = {
  [NodeType.Text]: {
    // 文字内容
    text: '',
    // 文字大小
    fontSize: 0,
    // 字体粗细
    fontWeight: 0,
    // 文字是否倾斜
    italic: false,
    // 字体间距
    letterSpacing: 0,
    // 行间距
    lineHeight: {
      type: 'percent',
      value: 1.5, // 150%
    },
  },
}

// 是否选择了单个元素
const single = ref(false)
// 当前选择的元素类型
const tag = ref('')
// 当前选择的元素
let currentNode: UI | undefined
const getFormSelect = () => {
  return currentNode
}
provide(formSelectInjectKey, getFormSelect)

watch(
  form,
  (value) => {
    if (!currentNode) {
      return
    }

    Object.keys(value).forEach((key) => {
      // 排除空数据
      if (value[key] === '') {
        return
      }
      currentNode[key] = value[key]
    })
  },
  {
    deep: true,
  }
)
watch(
  appForm,
  (value) => {
    const leafer = leaferApp!.value
    if (!leafer) {
      return
    }

    Object.keys(value).forEach((key) => {
      // 排除空数据
      if (value[key] === '') {
        return
      }
      leafer[key] = value[key]
    })
  },
  {
    deep: true,
  }
)

const selectSize = ref(0)
const setAppForm = () => {
  if (!leaferApp || !leaferApp.value) {
    return
  }
  const leafer = leaferApp.value
  Object.keys(appForm.value).forEach((key) => {
    if ('fill' === key && typeof leafer[key] !== 'string') {
      return
    }

    appForm.value[key] = leafer[key] as any
  })
}

/**
 * 更新表单数据
 * @param value
 */
const updateForm = (value: UI) => {
  if (!value) {
    return
  }
  // 如果属性不存在则添加属性
  if (Object.prototype.hasOwnProperty.call(attrs, value.tag)) {
    form.value = Object.assign({}, cloneDeep(initForm), cloneDeep(attrs[value.tag]))
  }

  // 获取元素的样式
  Object.keys(form.value).forEach((key) => {
    // 单独处理自定义数据
    if ('data' === key) {
      userDataTemp.value = JSON.stringify(value[key])
    }
    // 统一把文字粗细转换为数值
    if (key === 'fontWeight' && typeof value[key] === 'string') {
      value[key] = 400
    }
    form.value[key] = value[key] as any
  })
  if (!form.value.dashPattern) {
    form.value.dashPattern = [0, 0]
  }
  if (!form.value.dashOffset) {
    form.value.dashOffset = 0
  }
  // 获取当前的元素类型
  tag.value = value.tag
}
/**
 * 选择元素事件
 * @param e
 */
const selectEvent = (e: EditorEvent) => {
  // 每次点击的时候先清除上次选择的元素
  currentNode = undefined
  if (!leaferApp || !leaferApp.value) {
    return
  }
  const leafer = leaferApp.value
  console.log('选择元素触发了')
  single.value = leafer.editor.single
  selectSize.value = leafer.editor.list.length
  if (selectSize.value === 0) {
    setAppForm()
  }

  // 如果不是单向的则暂时不处理
  if (!single.value) {
    return
  }
  const value = e.value as UI
  updateForm(value)

  nextTick().then(() => {
    currentNode = value
  })
}

const init = (): void => {
  if (!leaferApp || !leaferApp.value) {
    return
  }
  console.log('表单初始化')
  const leafer = leaferApp.value
  setAppForm()
  /**
   * 监听选择事件
   */
  leafer.editor.on(EditorEvent.SELECT, selectEvent)
  /**
   * 监听移动 缩放, 旋转, 倾斜
   */
  leafer.editor.on(
    [EditorMoveEvent.MOVE, EditorScaleEvent.SCALE, EditorRotateEvent.ROTATE, EditorSkewEvent.SKEW],
    () => {
      // console.log('触发了编辑')
      if (currentNode) {
        updateForm(currentNode)
      }
    }
  )
}
watchEffect(() => {
  if (leaferApp && leaferApp.value) {
    init()
  }
})
// 属性绑定的值
const activeName = ref('1')
// tab标签页绑定的值
const activeTabName = ref('1')
watch(selectSize, (v) => {
  if (v === 0) {
    activeTabName.value = '1'
  }
})
// 动画组件
const LeafterAnimation = loadAsyncComponent(() => import('./LeafterAnimation.vue'))
</script>

<template>
  <el-form :model="form" label-width="100px" style="width: 100%">
    <el-tabs v-model="activeTabName">
      <el-tab-pane label="属性配置" name="1">
        <el-collapse v-model="activeName" accordion v-if="single">
          <el-collapse-item title="位置属性" name="1">
            <el-form-item label="层级">
              <el-input-number v-model="form.zIndex" />
            </el-form-item>
            <el-form-item label="x轴坐标">
              <el-input-number v-model="form.x" />
            </el-form-item>
            <el-form-item label="y轴坐标">
              <el-input-number v-model="form.y" />
            </el-form-item>
            <el-form-item label="宽度">
              <el-input-number v-model="form.width" />
            </el-form-item>
            <el-form-item label="高度">
              <el-input-number v-model="form.height" />
            </el-form-item>
            <el-form-item label="旋转角度">
              <el-input-number v-model="form.rotation" />
            </el-form-item>
            <el-form-item label="x轴缩放">
              <el-input-number v-model="form.scaleX" />
            </el-form-item>
            <el-form-item label="y轴缩放">
              <el-input-number v-model="form.scaleY" />
            </el-form-item>
            <el-form-item label="x轴倾斜">
              <el-input-number v-model="form.skewX" />
            </el-form-item>
            <el-form-item label="y轴倾斜">
              <el-input-number v-model="form.skewY" />
            </el-form-item>
          </el-collapse-item>

          <el-collapse-item title="样式属性" name="2">
            <el-form-item label="填充颜色" v-if="showFill" v-show="form.fill">
              <el-color-picker v-model="form.fill" />
            </el-form-item>
            <el-form-item label="描边颜色">
              <el-color-picker v-model="form.stroke" />
            </el-form-item>
            <el-form-item label="描边宽度">
              <el-input-number v-model="form.strokeWidth" />
            </el-form-item>
            <el-form-item label="描边端点">
              <el-select v-model="form.strokeCap">
                <el-option value="none">无</el-option>
                <el-option value="round">圆形</el-option>
                <el-option value="square">方形</el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="描边拐角">
              <el-select v-model="form.strokeJoin">
                <el-option value="miter">直角</el-option>
                <el-option value="bevel">平角</el-option>
                <el-option value="round">圆角</el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="虚线描边数值">
              <el-input-number
                :model-value="form.dashPattern[0]"
                @change="($event) => (form.dashPattern[0] = $event)"
              />-
              <el-input-number
                :model-value="form.dashPattern[1]"
                @change="($event) => (form.dashPattern[1] = $event)"
              />
            </el-form-item>
            <el-form-item label="虚线描边起点偏移">
              <el-input-number v-model="form.dashOffset" />
            </el-form-item>
          </el-collapse-item>

          <el-collapse-item title="控制属性" name="3">
            <!--        <el-form-item label="是否可编辑">
          <el-switch v-model="form.editable"></el-switch>
        </el-form-item>-->
            <el-form-item label="是否锁定">
              <el-switch v-model="form.locked"></el-switch>
            </el-form-item>
            <el-form-item label="锁定宽高比">
              <el-switch v-model="form.lockRatio"></el-switch>
            </el-form-item>
          </el-collapse-item>

          <el-collapse-item title="数据属性" name="4">
            <el-form-item label="元素id">
              <el-input v-model="form.id"></el-input>
            </el-form-item>
            <el-form-item label="用户数据">
              <el-input v-model="userDataTemp" type="textarea" @blur="userDataChange"></el-input>
            </el-form-item>
          </el-collapse-item>

          <el-collapse-item title="内容属性" name="5" v-if="tag === NodeType.Text">
            <el-form-item label="文字内容">
              <el-input v-model="form.text" type="text"></el-input>
            </el-form-item>
            <el-form-item label="文字大小">
              <el-input-number v-model="form.fontSize"></el-input-number>
            </el-form-item>
            <el-form-item label="行高">
              <el-input-number v-model="form.lineHeight.value"></el-input-number>
            </el-form-item>
            <el-form-item label="字体粗细">
              <el-input-number v-model="form.fontWeight"></el-input-number>
            </el-form-item>
          </el-collapse-item>
        </el-collapse>

        <template v-if="selectSize === 0">
          <el-form-item label="填充颜色">
            <el-color-picker v-model="appForm.fill" />
          </el-form-item>
          <el-form-item label="画布宽度">
            <el-input-number v-model="appForm.width" :min="0" />
          </el-form-item>
          <el-form-item label="画布高度">
            <el-input-number v-model="appForm.height" :min="0" />
          </el-form-item>
        </template>
      </el-tab-pane>
      <el-tab-pane label="动画" name="2" v-if="single">
        <LeafterAnimation></LeafterAnimation>
      </el-tab-pane>
    </el-tabs>
  </el-form>
</template>

<style scoped lang="scss"></style>
